#ifndef _MAP_OBJECT_H_
#define _MAP_OBJECT_H_

#include <utilities/utilities.h>
#include <vector>
#include <map>
#include <dispatch_system/definitions.h>
#include <string>

namespace moying
{
namespace navigation
{
    class MapObject
    {
        public:
            MapObject()
            :type_("Unknown"), name_("Unknown")
            {

            }
            MapObject(const std::string type, const std::string name)
            :type_(type), name_(name)
            {

            }
            inline std::string getType()
            {
                return type_;
            }

            inline std::string getName()
            {
                return name_;
            }
            void setColor(const ColorRGBA &color)
            {
                color_ = color;
            }

            void setColor(double r, double g, double b, double a)
            {
                color_.r = r;
                color_.g = g;
                color_.b = b;
                color_.a = a;
            }

            ColorRGBA getColor()
            {
                return color_;
            }
        private:
            ColorRGBA color_;
            std::string type_;
            std::string name_;
    };
    typedef std::shared_ptr<MapObject> MapObjectPtr;
    
    class LocalObstacle: public MapObject
    {
        public:
            LocalObstacle()
            :MapObject("LocalObstacle", "LocalObstacle")
            {

            }
    };
    typedef std::shared_ptr<LocalObstacle> LocalObstaclePtr;

    class VehicleInflation;
    typedef std::shared_ptr<VehicleInflation> VehicleInflationPtr;
    class VehicleInflation: public MapObject
    {
        public:
            VehicleInflation()
            :MapObject("VehicleInflation", "VehicleInflation")
            {
                setColor(0,1,0,0.3);//透明绿色
                // setColor(1,1,1,0.2);//透明白色
            }

            virtual ~VehicleInflation()
            {

            }

            inline void registerVehicle(const MapObjectPtr &vehicle)
            {
                inflated_vehicles_.emplace(vehicle);
            }
            inline void unregisterVehicle(const MapObjectPtr &vehicle)
            {
                inflated_vehicles_.erase(vehicle);
            }
            inline bool hasUniqueVehicle(const MapObjectPtr &vehicle)
            {
                return inflated_vehicles_.size() == 1 && (*inflated_vehicles_.begin() == vehicle);
            }
            inline bool empty()
            {
                return inflated_vehicles_.size() == 0;
            }
            inline bool canOccupy(const MapObjectPtr &vehicle){
                return empty() || hasUniqueVehicle(vehicle);
            }

            inline void showVehicles(){
                if(empty())
                    return;
            //     for(auto v : inflated_vehicles_){
            //         VehicleInflationPtr vehicle_inflation = std::static_pointer_cast<VehicleInflation>(v);
            //         printf("---- occupy vehicle name:%s,type:%s\n",v->getName().c_str(),v->getType().c_str());
            //     }
            }
        private:
            std::set<MapObjectPtr> inflated_vehicles_;
    };
    
}
}
#endif